﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using System.Net;
using System.Web;
using System.Threading;
using HtmlAgilityPack;
namespace LyricFinder
{
    public class LyricComponent
    {
        private HtmlWeb htmlweb = new HtmlWeb();
        private HtmlDocument htmldoc = new HtmlDocument();

        public List<string> getList(string keyword, int searchby)
        {
            bool checkcon = CheckForInternetConnection();
            List<string> list = new List<string>();
            if (checkcon)
            {
                if (searchby == 1) getPageByTitle(keyword);
                else if (searchby == 3) getPageByAlbum(keyword);
                else if (searchby == 4) getPageByLyricPart(keyword);

                HtmlNodeCollection nodestitle = htmldoc.DocumentNode.SelectNodes("//h3/a");
                List<string> listtitle = new List<string>();

                if (nodestitle != null)
                {
                    foreach (HtmlNode node in nodestitle)
                    {
                        string title = node.InnerText.ToString();
                        string[] titlesplit = title.Split(' ');
                        title = "";
                        for (int i = 0; i < titlesplit.Length - 1; i++)
                        {
                            if (i == titlesplit.Length - 2)
                            {
                                title += titlesplit[i];
                            }
                            else
                            {
                                title += (titlesplit[i] + " ");
                            }
                        }
                        listtitle.Add(title);
                    }
                }

                HtmlNodeCollection nodesartist = htmldoc.DocumentNode.SelectNodes("//div[@class='serpdesc-2']/p/a[1]");
                List<string> listartists = new List<string>();
                if (nodesartist != null)
                {
                    foreach (HtmlNode node in nodesartist)
                    {
                        string artist = node.InnerText.ToString();
                        listartists.Add(artist);
                    }
                }
                for (int i = 0; i < listtitle.Count; i++)
                {
                    list.Add(listtitle[i] + "," + listartists[i]);
                }
            }
            else
            {
                list.Add("Cannot connect to www.songlyrics.com");
            }

            //remove duplications
            for (int i = 0; i < list.Count; i++)
            {
                for (int j = 0; j < i; j++)
                {
                    if (list[j].Equals(list[i]))
                    {
                        list.RemoveAt(j);
                    }
                }
            }
            return list;
        }

        public List<string> getListByArtist(string keyword)
        {
            bool checkcon = CheckForInternetConnection();
            List<string> list = new List<string>();
            if (checkcon)
            {
                //this part of code is to get the number of maximum pages of result of the intended artist
                /*getPageByArtist(keyword, 1);
                HtmlNode nodepage = htmldoc.DocumentNode.SelectSingleNode("//ul[@class='pagination'][1]/li[last()-1]/a");
                int page = 0;
                if (nodepage != null)
                {
                    string strpage = nodepage.InnerText.ToString();
                    page = Convert.ToInt32(strpage);
                }*/

                //loop and parse through pages 
                for (int i = 1; i <= 2; i++) //limited only to 2 pages for faster performance
                {
                    getPageByArtist(keyword, i);
                    HtmlNodeCollection nodestitle = htmldoc.DocumentNode.SelectNodes("//h3/a");
                    List<string> listtitle = new List<string>();

                    if (nodestitle != null)
                    {
                        foreach (HtmlNode node in nodestitle)
                        {
                            string title = node.InnerText.ToString();
                            string[] titlesplit = title.Split(' ');
                            title = "";
                            for (int j = 0; j < titlesplit.Length - 1; j++)
                            {
                                if (j == titlesplit.Length - 2)
                                {
                                    title += titlesplit[j];
                                }
                                else
                                {
                                    title += (titlesplit[j] + " ");
                                }
                            }
                            listtitle.Add(title);
                        }
                    }

                    HtmlNodeCollection nodesartist = htmldoc.DocumentNode.SelectNodes("//div[@class='serpdesc-2']/p/a[1]");
                    List<string> listartists = new List<string>();
                    if (nodesartist != null)
                    {
                        foreach (HtmlNode node in nodesartist)
                        {
                            string artist = node.InnerText.ToString();
                            listartists.Add(artist);
                        }
                    }
                    for (int j = 0; j < listtitle.Count; j++)
                    {
                        list.Add(listtitle[j] + "," + listartists[j]);
                    }
                }
            }
            else
            {
                list.Add("Cannot connect to www.songlyrics.com");
            }

            //remove duplications
            for (int i = 0; i < list.Count; i++)
            {
                for (int j = 0; j < i; j++)
                {
                    if (list[j].Equals(list[i]))
                    {
                        list.RemoveAt(j);
                    }
                }
            }
            return list;
        }

        public List<string> getListByTags(string keyword)
        {
            //get list of songs with the keyword as lyric part
            List<string> templist = getList(keyword, 4);
            //make a new list of songs with the intended tags
            List<string> list = new List<string>();
            if (templist.Count == 0 || templist[0].Equals("Cannot connect to www.songlyrics.com"))
            {
                list.Add("Cannot connect to www.songlyrics.com");
            }
            else
            {
                //get the lyric
                List<string> songs = new List<string>();
                for (int i = 0; i < templist.Count; i++)
                {
                    string lyrics = getLyric(templist[i]);
                    songs.Add(lyrics);
                }

                //count the number of words matching the keyword/tag
                int count = 0;
                for (int i = 0; i < songs.Count; i++)
                {
                    string[] songparts = songs[i].Split(' ');
                    for (int j = 0; j < songparts.Length; j++)
                    {
                        if (songparts[j].Contains(keyword)) count++;
                    }
                    if (count >= 10)
                    {
                        list.Add(templist[i]);
                    }
                }
            }
            return list;
        }

        private static bool CheckForInternetConnection()
        {
            try
            {
                using (var client = new WebClient())
                using (var stream = client.OpenRead("http://www.songlyrics.com"))
                {
                    return true;
                }
            }
            catch
            {
                return false;
            }
        }

        private void getPageByTitle(string keyword)
        {
            string url = "http://www.songlyrics.com/index.php?section=search&searchW=" + keyword + "&submit=Search&searchIn3=song";
            htmldoc = htmlweb.Load(url);
        }

        private void getPageByArtist(string keyword, int page)
        {
            string url = "";
            if (page == 1)
            {
                url = "http://www.songlyrics.com/index.php?section=search&searchW=" + keyword + "&submit=Search&searchIn1=artist";
                htmldoc = htmlweb.Load(url);
            }
            else
            {
                url = "http://www.songlyrics.com/index.php?section=search&searchIn1=artist&searchW=" + keyword + "&pageNo=" + page;
                htmldoc = htmlweb.Load(url);
            }
        }

        private void getPageByAlbum(string keyword)
        {
            string url = "http://www.songlyrics.com/index.php?section=search&searchW=" + keyword + "&submit=Search&searchIn2=album";
            htmldoc = htmlweb.Load(url);
        }

        private void getPageByLyricPart(string keyword)
        {
            string url = "http://www.songlyrics.com/index.php?section=search&searchW=" + keyword + "&submit=Search&searchIn4=lyrics";
            htmldoc = htmlweb.Load(url);
        }

        private void getLyricPage(string keyword)
        {
            keyword = keyword.ToLower();
            string[] search = keyword.Split(',');
            
            //get title
            string[] titlesplit = search[0].Split(' ');
            string title = "";
            for (int i = 0; i < titlesplit.Length; i++)
            {
                title += (titlesplit[i] + "-");
            }
            //get artist dir
            string[] artistsplit = search[1].Split(' ', '.','&','(',')');
            string artist = "";
            for (int i = 0; i < artistsplit.Length; i++)
            {
                if (i==artistsplit.Length-1)
                {
                    artist += artistsplit[i];
                }
                else
                {
                    artist += (artistsplit[i] + "-");
                }
            }
            string url = "http://www.songlyrics.com/" + artist + "/" + title + "lyrics/";
            htmldoc = htmlweb.Load(url);
        }

        public string getLyric(string title)
        {
            getLyricPage(title);
            HtmlNodeCollection nodelyric = htmldoc.DocumentNode.SelectNodes("//p[@id='songLyricsDiv']");

            string lyricdecode = "";
            if (nodelyric != null)
            {
                foreach (HtmlNode node in nodelyric)
                {
                    string decode = node.InnerText.ToString();
                    decode = HttpUtility.HtmlDecode(decode);
                    lyricdecode += decode;
                }
            }

            string info = getInfo(htmldoc, title);
            string lyric = info + lyricdecode;
            return lyric;
        }

        private string getInfo(HtmlDocument doc, string title)
        {
            string[] info = title.Split(',');
            string infotitle = info[0];
            string infoartist = info[1];
            string songinfo = "Title : " + infotitle + "\nArtist : " + infoartist;
            HtmlNode nodealbum = htmldoc.DocumentNode.SelectSingleNode("//div[@class='pagetitle']/p[2]/a");
            if (nodealbum != null)
            {
                songinfo += ("\nAlbum : "+ nodealbum.InnerText.ToString());
            }
            
            HtmlNode nodegenre = htmldoc.DocumentNode.SelectSingleNode("//div[@class='pagetitle']/p[3]/a");
            if (nodegenre != null)
            {
                songinfo += ("\nGenre : "+ nodegenre.InnerText.ToString());
            }
            songinfo += "\n\n";
            
            return songinfo;
        }
    }
}
